一句话理解: Agent 的可靠性不来自更强的模型,而来自你围绕它搭建的控制系统。这套控制系统,就是 Harness。
引言:为什么你的 AI Agent 总是"差一点"?
2026 年初,一个令人不安的共识正在形成:模型越来越强,但 Agent 并没有等比例变得更可靠。
你可能也有过这样的体验——让 AI 帮你写代码,它能写出来,但总会犯一些"本不该犯的错":用错 API、忽略项目规范、跑偏架构、漏掉分区条件。你反复纠正,它反复犯。你开始怀疑:是不是模型还不够强?
答案可能出乎意料:问题往往不在模型,而在模型周围的一切。
2026 年 2 月,Mitchell Hashimoto(HashiCorp 联合创始人、Terraform 作者)在一篇博文里给这个"模型周围的一切"起了个名字——Harness Engineering。随后的几周里,OpenAI、Martin Fowler / Thoughtworks、LangChain 几乎同时从不同角度验证了同一个判断:
Agent = Model + Harness。模型是马,Harness 是缰绳。
这篇文章试图帮你理解:Harness Engineering 是怎么发展起来的,它到底在说什么,以及它对你构建 AI Agent 意味着什么。
一、概念是怎么诞生的:三周内的行业共振
1.1 Mitchell Hashimoto:给实践起个名字
2026 年 2 月 5 日,Mitchell Hashimoto 发表了 My AI Adoption Journey。这篇文章把自己从 AI 怀疑论者到深度使用者的过程分成了六个阶段。在第五步 "Engineer the Harness" 里,他写道:
他不确定行业是否已经有通用术语,但他开始把这个实践叫做 "harness engineering"——每当 agent 犯了一个错,就花时间设计一个方案,让它以后不再犯。
他描述了两种具体形式:
- 隐式提示(implicit prompting):通过
AGENTS.md文件把行为约束编码进项目 - 程序化工具:截图脚本、过滤测试运行器、验证流程
关键洞察是结构性的,不是语言性的:当 agent 犯错时,你不应该改 prompt 的措辞,而应该改变系统,让那个错误在机制上变得不可能再发生。
1.2 OpenAI:用百万行代码验证
仅仅六天后(2 月 11 日),OpenAI 发表了 Harness engineering: leveraging Codex in an agent-first world。文章记录了一个惊人的实验:三名工程师(后来增至七人),在五个月内,从空 Git 仓库构建了一个百万行代码级别的内部产品——全部代码由 Codex 生成,没有人类手写代码。
但这篇文章真正的价值不在那些数字,而在一个更深的判断:
"人类掌舵,智能体执行。"(Human steers, agents execute.)
OpenAI 发现,早期进展缓慢不是因为模型不行,而是因为环境规范不够清楚、缺少工具和抽象层。真正的瓶颈是运行环境是否为 agent 优化。
1.3 Birgitta Böckeler / Thoughtworks:冷静的框架化
2 月 17 日,Thoughtworks 的 Distinguished Engineer Birgitta Böckeler 在 martinfowler.com 发表了第一篇分析备忘录。她没有被案例冲昏头,而是踩了一脚刹车:
OpenAI 展示的主要是长期可维护性机制,但对"功能与行为验证"讲得不够。
随后在 4 月 2 日,她发表了更成熟的 Harness engineering for coding agent users,提出了 Guides / Sensors 和 Computational / Inferential 的二维框架——这是目前为止最系统的 Harness 思考模型。
1.4 LangChain:概念解剖
3 月,LangChain 发表了 The Anatomy of an Agent Harness,给出了最简洁的定义:
"If you're not the model, you're the harness."
Agent = Model + Harness。Harness 是所有不属于模型本身、但让 agent 真正运转的代码、配置和执行逻辑。
1.5 时间线总结
| 日期 | 事件 | 角色 |
|---|---|---|
| 2026-02-05 | Mitchell Hashimoto 发表 My AI Adoption Journey | 命名者 |
| 2026-02-11 | OpenAI 发表 Harness Engineering | 大规模验证者 |
| 2026-02-12 | Can Boluk 展示 harness 变化带来 6.7% → 68.3% 的性能跳升 | 实证数据 |
| 2026-02-17 | Böckeler 发表 First Thoughts Memo | 批判性分析 |
| 2026-03-10 | LangChain 发表 Anatomy of an Agent Harness | 概念解剖 |
| 2026-04-02 | Böckeler 发表 完整框架文章 | 控制框架成型 |
这种"多方几乎同时发现"的节奏说明:大家其实早就在做 Harness Engineering,只是缺一个名字。
二、Harness 到底是什么
2.1 核心公式
Agent = Model + Harness
- Model = 大脑,负责推理和生成
- Harness = 神经系统、手脚、记忆、规则、反馈回路
- Agent = 能在真实环境中持续完成任务的整体系统
打个比方:模型是马——强壮、快速,但没有方向感。Harness 是缰绳、马鞍和马蹬——把力量引向正确的方向。工程师是骑手——决定去哪里。
2.2 Harness 包含什么
按 LangChain 和 Böckeler 的综合视角,一个完整的 Harness 至少涉及:
- 指令层:System Prompt、AGENTS.md、项目规则、输出协议
- 状态层:任务进度、中间产物、历史操作、错误记录
- 工具层:文件读写、代码执行、API 调用、搜索
- 约束层:白名单、黑名单、最大步数、架构边界、依赖方向
- 验证层:测试、lint、schema 校验、success criteria
- 反馈层:错误信号回灌、自纠提示、人工审查触发
- 追踪层:全链路日志、token 消耗、调用轨迹、耗时
2.3 Böckeler 的二维控制框架
这是目前最清晰的 Harness 思考模型,来自 Harness engineering for coding agent users:
第一维度:控制方向
| 定义 | 作用时机 | 目标 | |
|---|---|---|---|
| Guides(前馈控制) | 预判行为,提前引导 | agent 行动前 | 提高一次做对的概率 |
| Sensors(反馈控制) | 观察结果,帮助自纠 | agent 行动后 | 让错误在到达人眼前就被修正 |
第二维度:执行方式
| 特点 | 速度 / 成本 | 典型例子 | |
|---|---|---|---|
| Computational | 确定性、CPU 执行 | 快、便宜、可靠 | lint、type check、tests、structural analysis |
| Inferential | 语义判断、LLM 执行 | 慢、贵、非确定 | AI code review、LLM-as-judge |
这给出了一个实用的 2×2 矩阵。核心启示是:不要把所有质量问题都交给 LLM——确定性工具能解决的,就别用推理。
Böckeler 还特别指出,当 sensor 产生的信号为 LLM 消费做了优化时,效果会特别强——比如 custom linter message 里带着自纠指令。她半开玩笑地称之为"一种积极的 prompt injection"。
三、Harness Engineering 与相邻概念的关系
3.1 演进路径:Prompt → Context → Harness
这三个概念形成了嵌套递进的关系:
- Prompt Engineering(2022–2024):关注"怎么跟模型说"——措辞、few-shot、角色扮演。作用域是单次交互。
- Context Engineering(2025):关注"模型看到了什么"——检索、状态摘要、上下文窗口管理。作用域是多轮交互。
- Harness Engineering(2026):关注"整个系统怎么运转"——环境、约束、工具、反馈回路、验证、治理。作用域是整个 Agent 运行时。
关键区别在于执行力:
- Prompt Engineering 可以影响但不能阻止坏行为
- Context Engineering 确保模型有信息但不能结构性阻断错误输出
- Harness Engineering 可以机械性地阻止整类失败——当 linter 拒绝违反分层规则的代码时,这个边界是绝对的
Böckeler 在她的完整框架文章里给出了一个明确的从属关系:
Context Engineering 提供了让 guides 和 sensors 可供 agent 使用的手段。为 coding agent 搭建用户侧 harness,是 context engineering 的一种具体形式。
也就是说:Context Engineering 是 Harness 的子集,而不是平级概念。
3.2 与其他概念的关系速查
| 概念 | 与 Harness 的关系 |
|---|---|
| Agent | Agent = Model + Harness(包含关系) |
| Prompt Engineering | Harness 的一个局部子集 |
| Context Engineering | Harness 的核心子系统 |
| Workflow | Harness 的运行骨架之一 |
| Guardrails | Harness 的约束子集 |
| Evaluation | Harness 的验证子系统 |
| Observability | Harness 的感知与反馈子系统 |
四、Harness 是分层的,不是铁板一块
4.1 三类调节目标
Böckeler 在她的框架文章里把 Harness 按调节目标分成三类:
1. Maintainability Harness(可维护性)
- 调节内部代码质量:重复、复杂度、风格、架构漂移
- 最容易入手,因为已有大量现成工具(lint、type check、coverage)
- OpenAI 那篇文章展示最多的就是这一层
2. Architecture Fitness Harness(架构适应性)
- 用 fitness functions 定义和检查架构特性
- 包括性能要求、observability 规范、安全约束
- 例如:要求"启动必须在 800ms 内"、"关键路径 span 不超过 2 秒"
3. Behaviour Harness(行为正确性)
- 确保系统功能按预期工作
- 这是 Böckeler 所说的 "elephant in the room"——最重要,也最难
- 现在很多做法是 "AI 生成测试 + 看是否全绿",但她明确警告:对 AI 生成测试抱过大信心,目前还不够好
4.2 不同任务需要不同的 Harness "配方"
一个关键洞察是:Harness 不是一套固定模板,而是"通用控制骨架 + 任务域特化 + 项目级配置"的组合体。
通用 Harness Core(guides / sensors / state / tools / verification / tracing)
└── Coding Harness Pack
└── TypeScript / Next.js Pack
└── 项目级 Repo Rules
└── 当前任务临时约束
即使都是 Coding Agent:
- 写前端 UI 的 Harness ≠ 写后端服务的 Harness
- 写基础设施代码的 Harness ≠ 写数据脚本的 Harness
它们共享控制骨架,但 guides 的内容、sensors 的检查项、verification 的标准,都会因任务而异。
五、从 OpenAI 案例看 Harness 的工程落地
OpenAI 的文章不只是一个案例展示,它实际上回答了一个更深的问题:当代码主要由 agent 生成时,工程系统本身需要怎么重构?
5.1 Repo 是 Agent 的世界模型
OpenAI 做了一个很激进的决定:把代码仓库当成 record system(记录系统)。设计文档、架构文档、执行计划、技术债、产品规格、引用资料,全部集中版本化存储在 repo 里。
原因很直白:对 agent 来说,看不到的东西就等于不存在。 存在 Google Docs、聊天记录或人脑里的知识,agent 都无法使用。
5.2 大而全的 AGENTS.md 失败了
他们早期尝试过把所有规则写进一个大型 AGENTS.md,但发现不可持续。最后改成了渐进式披露(progressive disclosure):
- AGENTS.md 变成短小的"目录页",只给地图和入口
- 真正的知识结构化存放在
docs/目录下 - Agent 按需逐层查阅,而不是一次性被淹没
5.3 用 Lint 和结构测试强制执行"品味"
OpenAI 反复强调一点:不是微观控制实现细节,而是强制不变量(enforced invariants):
- 分层依赖方向
- 边界处数据形状验证
- 结构化日志
- 类型命名规范
- 文件大小限制
这些不是"建议",而是通过自定义 lint 和结构测试机械执行的规则。
5.4 用后台 Agent 做"垃圾回收"
最令人印象深刻的实践之一:他们把"黄金原则"编码进仓库,然后让后台 Agent 持续扫描偏差、更新质量分数、提交重构 PR。
这把传统的"季度技术债清理"改造成了持续运行的自动化治理工作流。
六、产品级 Agent 的双层 Harness 结构
一个容易被忽略但非常重要的认知是:产品级 coding agent(如 Claude Code、Cursor、Codex)本身已经自带一层厂商内置 Harness,但它不可能天然适配所有仓库和团队。
这意味着存在两层 Harness:
第一层:厂商内置 Harness
产品级 Agent 内部已经包含:
- Agent Loop(循环执行机制)
- Context Management(上下文管理)
- 内置工具(文件读写、命令执行、搜索)
- 安全控制(危险操作拦截)
- 产品级默认行为
第二层:用户 / 项目侧 Harness
厂商同时暴露出扩展接口,让用户按项目定制:
| 扩展点 | 性质 | Harness 角色 |
|---|---|---|
CLAUDE.md / AGENTS.md | 项目级指令文件 | 软 Guide |
| Skills | 可复用能力包 | 任务域特化 |
| Hooks | 生命周期节点触发 | 硬 Control(确定性执行) |
| Commands | 自定义命令 | 快捷工作流 |
| MCP / Plugins | 外部服务接入 | 环境扩展 |
| Settings | 层级化配置 | Policy / Config |
优秀的产品级 Agent,不是替用户把 Harness 全做完,而是把"可被用户继续 harness"的接口设计出来。
像 Superpowers 和 GStack 这类社区项目,本质上就是在这些扩展接口之上,组装出更具体的用户侧工作流和控制包。它们虽然不一定显式使用 "Harness" 这个词,但做的事情——规划、测试、评审、QA、约束——本质上就是 Harness Engineering。
七、最小 Harness MVP:从哪里开始
如果你想在自己的项目中开始实践 Harness Engineering,不需要一步到位。以下是一个最小可落地的模块清单:
User Task
↓
[1] Instruction Layer ← AGENTS.md / 项目规则 / 输出格式
↓
[2] Orchestrator ← Agent Loop:调模型 → 调工具 → 更新状态 → 判断继续/结束
↙ ↘
[3] State [4] Tools ← 当前目标、步骤进度、中间结果 / 文件读写、测试、搜索
↘ ↙
[5] Verification ← schema 校验 / tests / lint / success criteria
↓
[6] Tracing ← 全链路记录:输入、输出、工具调用、状态变化、错误、耗时
↓
[7] Human Review / Output
建议顺序:
- 先跑通闭环:输入 → 调模型 → 调 1-2 个工具 → 返回结果 → 记录 trace
- 补 State:把任务进度和中间结果写进状态,不要只靠历史消息堆上下文
- 补 Verification:先让系统知道"什么时候算错"——这是从 demo 到可用工具的关键跳跃
- 补 Guardrails:白名单、最大步数、危险动作拦截——这是从可用到敢用
- 最后加 Skills / Sub-agents / Middleware:在最小闭环稳定后再扩展
八、一个真实的 Harness 实践:从痛点到落地
理论讲到这里,你可能还是觉得 Harness Engineering 是个"大公司才能做的事"。但其实,任何一个用 Claude Code 写项目的个人开发者,都已经站在 Harness Engineering 的起点上了。
下面是一个真实的例子:我在使用 Claude Code 开发项目时,遇到了一个反复出现的痛点,然后一步步设计出了一个最小 harness——事后回头看,才发现它恰好落进了 Böckeler 框架的每一个格子里。
8.1 痛点:每次重新开始,agent 都"失忆"了
用 Claude Code 开发时,最让我抓狂的不是模型写错代码,而是每次关掉 session 重新打开,它完全不知道上次做到哪了。它会重新探索项目结构,问一些早就回答过的问题,甚至重复做已经完成的工作。
这个问题的根源很清楚:session 之间没有持久化的项目状态。 agent 的"记忆"只存在于当前会话的上下文窗口里,关掉就没了。
8.2 第一反应:在 CLAUDE.md 里写项目说明?
我最初的 CLAUDE.md 长这样:
Use first-principles thinking. Avoid empiricism...
Language preference: Always default to Simplified Chinese...
全是思维方式和输出格式。这些很有用,但它们回答的是"怎么思考",没有回答"这个项目是什么、现在做到哪了"。
就像一个新同事每天早上来上班都失忆了——你给他一本《如何优雅地写代码》没有用,你需要在他桌上放一张纸:这个项目做什么、现在到哪一步了、哪些文件不能乱动。
8.3 设计方案:STATUS.md + 自动总结 + 定期压缩
经过思考,我设计了一个很简单的机制:
1. 分离稳定信息和动态信息
CLAUDE.md里写稳定不变的——项目是什么、技术栈、核心目录、不能乱改的东西docs/STATUS.md里写持续变化的——每次 session 做了什么、当前进度、下一步计划
2. 每次 session 结束时,让 agent 自动总结追加到 STATUS.md
不需要我手动写。agent 自己知道这次做了什么,让它用几百字总结一下,追加写入。
3. 下次 session 开始时,CLAUDE.md 里有一条指令:"先读 docs/STATUS.md"
agent 一进来就知道上次做到哪了,不用重新探索。
4. 定期压缩
30 个 session 之后,STATUS.md 会很长。怎么办?——定期把旧记录压缩成一段"当前状态摘要",老的细节归档或删掉。这就是 OpenAI 文章里说的"垃圾回收",也是"渐进式披露"——agent 只需要读最新的压缩状态,需要历史细节时再往下查。
8.4 回头一看:这就是 Böckeler 的框架
设计完之后我才意识到,这个小机制恰好覆盖了 Böckeler 2×2 矩阵的三个格子:
| Guide(前馈) | Sensor(反馈) | |
|---|---|---|
| Computational | CLAUDE.md 里写"先读 STATUS.md" → agent 确定性地去读,不需要 LLM 判断 | — |
| Inferential | — | session 结束时让 LLM 总结本次做了什么 → 需要语义理解,无法用确定性程序完成 |
而定期压缩 STATUS.md,就是 OpenAI 所说的垃圾回收(garbage collection)——持续对抗信息膨胀带来的熵增。
8.5 从这个例子里学到的
这个例子最有价值的地方不在于方案本身多精巧,而在于它是怎么产生的:
- 从一个具体痛点出发:不是因为读了论文才去做,而是因为"agent 又失忆了"这件事太烦了
- 解决方案自然落进了理论框架:事后才发现它是 Guide + Sensor + Garbage Collection
- 不需要写复杂代码:只需要两个 markdown 文件 + 一条 CLAUDE.md 指令 + 一个 session 结束时的总结习惯
- 迭代改进:先做最简版(手动追加),再自动化(hook 触发),再治理(定期压缩)
这就是 Mitchell Hashimoto 说的那句话:agent 犯了错,就工程化地修一次。 你不需要一口气搭一个完美系统——每次解决一个具体问题,就是在做 Harness Engineering。
九、还没解决的问题
Harness Engineering 不是银弹。Böckeler 在她的框架文章里明确指出了几个未解难题:
9.1 Behaviour Verification 仍是最大缺口
当前的 Behaviour Harness 做法大致是:功能规格 → AI 生成测试 → 看是否全绿。但 Böckeler 直言:对 AI 生成测试套件抱这么大信心,现在还不够好。 我们离"足够增加信心以减少监督和手工测试"的好 harness 还有距离。
9.2 老系统 Retrofit 的成本
给旧代码库补装 Harness 可能代价极高。Böckeler 把它类比为"给从未做过静态分析的代码库突然上扫描器——可能直接被告警淹没"。从零构建 AI-friendly 系统,和给 legacy 系统 retrofit harness,可能是两类完全不同的工程问题。
9.3 Apprentice Gap
Martin Fowler 的网站上提到了 Renaud Wilsius 创造的术语 Apprentice Gap:如果我们过早地把人类放到 "on the loop" 的位置,可能会面临一个未来——没有人深入理解 "How",也就无法构建稳健的 Harness。 Harness Engineering 需要深厚的软件工程知识,但 Agent 本身可能减少了新人获得这种知识的机会。
9.4 人类判断力的编码
OpenAI 在文章最后坦承:他们仍在学习人类判断力在哪些地方最有价值,以及如何对这种判断力进行编码并放大。这个问题可能是 Harness Engineering 最深层的挑战——不是技术问题,而是认知问题。
十、我的理解与框架总结
经过对多篇核心文献的系统学习,我把 Harness Engineering 整理成以下认知框架:
一句话理解
Agent 的可靠性来自结构约束,不来自更好的指令。Harness 是让 Agent 从"能做"变成"可控地做对"的工程系统。
分层框架
┌─────────────────────────────────────────┐
│ Human Steering Loop │ ← 人类迭代 Harness,而不是手写代码
├─────────────────────────────────────────┤
│ Behaviour Harness (最难,仍未解) │ ← 功能行为验证
│ Architecture Fitness (fitness funcs) │ ← 非功能约束
│ Maintainability (最易,先做) │ ← 内部代码质量
├─────────────────────────────────────────┤
│ Guides (feedforward) │ Sensors (feedback)│ ← 核心控制方向
│ ├ computational │ ├ computational │
│ └ inferential │ └ inferential │ ← 执行方式
├─────────────────────────────────────────┤
│ State │ Tools │ Orchestrator │ Tracing │ ← 运行基础设施
├─────────────────────────────────────────┤
│ Model (LLM) │ ← 智能核心
└─────────────────────────────────────────┘
实践落地视角
- 从 Maintainability 入手:lint、tests、结构测试——现成工具最多,效果立竿见影
- 把错误转化为规则:每一次 agent 犯错,都写进 AGENTS.md 或变成检查脚本
- 优先 computational,谨慎 inferential:确定性工具能解决的,不要交给 LLM
- 质量左移(keep quality left):快的检查放 pre-commit,贵的检查放 pipeline
- 迭代 Harness,而不是盯 Agent:你的工作不是改代码,而是改控制系统
十一、推荐阅读顺序
如果你想从零开始系统学习 Harness Engineering,我建议按以下顺序阅读:
- My AI Adoption Journey — Mitchell Hashimoto — 实践觉醒篇:理解 Harness 从哪里长出来
- The Anatomy of an Agent Harness — LangChain — 概念解剖篇:理解 Harness 在概念上包含什么
- Harness Engineering — OpenAI — 系统落地篇:理解 Agent-first 工程如何改造真实系统
- Harness Engineering: First Thoughts — Böckeler — 批判补全篇:理解当前讨论还缺什么
- Harness Engineering for Coding Agent Users — Böckeler — 控制框架成型篇:获得可操作的 Guides / Sensors 框架
结语
Harness Engineering 的核心洞察,说到底就是一个反直觉的事实:给 Agent 更少的自由,反而让它更能干。
这和软件工程几十年的经验一脉相承——约束不是能力的敌人,而是可靠性的基础。类型系统约束了你的表达自由,但让程序更稳。CI/CD 约束了你的部署方式,但让交付更快。Lint 约束了你的代码风格,但让协作更顺。
Harness 对 Agent 做的,是同一件事。
而且它并不要求你是一个资深软件工程师才能开始。你用 Claude Code 时觉得 agent 老是失忆?写一个 STATUS.md,加一条自动加载指令——这就是你的第一个 harness。agent 总是用错 API?写进 CLAUDE.md——这就是你的第二个 harness。
Harness Engineering 不是一个你需要"学完才能开始"的学科。它是你每次解决一个具体问题时,自然会做的事。
严谨性没有消失。它只是从"人手写代码时的局部严谨",迁移到了"Agent 运行环境与控制系统的严谨"。
这就是 Harness Engineering 真正想说的。
本文基于 2026 年 2–4 月间多篇核心文献的系统学习与实践整理而成。作者:Jinkun